#include "desfire.h"
#include <stdlib.h>
#include "include/ca51f003_config.h"

#include "include/uart.h"




static uint8_t xdata pcb = 0x0a;

void pcb_init()
{
	pcb = 0x0a;
}

/**
 * @brief  ReadData 读标准数据文件和记录文件
 * @param  file_no: 1字节文件标识符
 * @param  offset: 3字节读的初始地址（偏移量）
 * @param  length: 3字节读的数据长度 
 * @param  buf: 读出的数据
 * @retval 
 */
int8_t Read_Cord_Data(uint8_t type,uint8_t file_no,uint8_t *offset,uint8_t *length,uint8_t command)
{
	uint32_t xdata len=0,j=0;
	uint8_t xdata buf[59];
	int8_t xdata status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 8;
	if(type == 0x00||type==0x01)
	{
		pcd_cmd.buff[0] = DESFIRE_READ_DATA; 
	}
	else
	{
		pcd_cmd.buff[0] = DESFIRE_READRECORD_FILE; 
	}
	pcd_cmd.buff[1] = file_no;
	memcpy(&pcd_cmd.buff[2],offset,3);
	memcpy(&pcd_cmd.buff[5],length,3);
	len = (len|length[2])<<16;
	len = (len|length[1])<<8;
	len = (len|length[0]);
	while(1)
	{
		status = des_cmd_transceive(pi);
		if(status == 0x00)
		{
			if(pcd_cmd.buff[0]==0x00)
			{
				memcpy(buf,&pcd_cmd.buff[1],pcd_cmd.length-1);
				uart_rec_buf(pcd_cmd.buff[0],command,buf,pcd_cmd.length-1);
				return MI_OK;
			}
			else if(pcd_cmd.buff[0]==0xaf)
			{
				memcpy(buf,&pcd_cmd.buff[1],pcd_cmd.length-1);
				uart_rec_buf(pcd_cmd.buff[0],command,buf,pcd_cmd.length-1);
				pcd_cmd.length = 1;
			}
			else
			{
				uart_rec_buf(pcd_cmd.buff[0],command,buf,0);
				return pcd_cmd.buff[0];
			}
		}
		else
		{
			return status;
		}
	}
}



/**
 * @brief  Create_Cyclic_LinearRecordFile 保存记录文件,支持备份机制特性 满则无法写入
 * @param  type: 3线性记录文件，4循环记录文件
 * @param  file_no: 1字节文件标识符
 * @param  size: 大小
 * @param  upper: 数量
 * @retval 
 */
int8_t Create_Cyclic_LinearRecordFile(uint8_t type,uint8_t file_no,uint8_t *size,uint8_t *num)
{
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 11;
	if(type == 3)
	{
		pcd_cmd.buff[0] = DESFIRE_LINEARRECORD_FILE; 
	}
	else if(type == 4)
	{
		pcd_cmd.buff[0] = DESFIRE_CYCLICCORD_FILE; 
	}
	pcd_cmd.buff[1] = file_no;
	pcd_cmd.buff[2] = 0x00;
	pcd_cmd.buff[3] = 0x00;
	pcd_cmd.buff[4] = 0x00;
	memcpy(&pcd_cmd.buff[5],size,3);
	memcpy(&pcd_cmd.buff[8],num,3);
	status = des_cmd_transceive(pi);
		if(status == MI_OK)
	{
		if(pcd_cmd.buff[0]==0x00)
		{
			return status;
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	return status;
}



/**
 * @brief  CreateStdDataFile  Create_Std_Backup_DataFile
 * @param  type: 非0带备份，0不带备份
 * @param  file_no: 1字节文件标识符
 * @param  size: 3字节文件大小以（32字节为单位）小端
 * @retval 
 */

int8_t Create_Std_Backup_DataFile(uint8_t type,uint8_t file_no,uint8_t *size)
{
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 8;
	if(0 == type)
	{
		pcd_cmd.buff[0] = DESFIRE_CREATESTD_FILE;  
	}
	else
	{
		pcd_cmd.buff[0] = DESFIRE_BACKUPDATA_FILE;  
	}
	pcd_cmd.buff[1] = file_no;
	pcd_cmd.buff[2] = 0x00;
	pcd_cmd.buff[3] = 0x00;
	pcd_cmd.buff[4] = 0x00;
	memcpy(&pcd_cmd.buff[5],size,3);
	status = des_cmd_transceive(pi);
		if(status == MI_OK)
	{
		if(pcd_cmd.buff[0]==0x00)
		{
			return status;
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	return status;
}



/**
 * @brief  write_std_Linear 写记录文件或者二进制文件
 * @param  type: 文件类型
 * @param  file_no: 1字节文件标识符
 * @param  offset: 3字节写入的初始地址（偏移量）
 * @param  length: 3字节写入的数据长度 
 * @param  data_buf: 写入的数据 
 * @retval 
 */
int8_t  write_std_Linear(uint8_t type,uint8_t file_no,uint8_t *offset,uint8_t *length,uint8_t *data_buf)
{
	uint32_t len=0;
	int8_t status = MI_EMPTY;
	uint8_t xdata i=0;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	if(type == 0x00||type == 0x01)
	{
		pcd_cmd.buff[0] = DESFIRE_WRITE_DATA;  
	}
	else if(type == 0x03||type == 0x04)
	{
		pcd_cmd.buff[0] = DESFIRE_WRITE_RECORD;
	}
	pcd_cmd.buff[1] = file_no;
	memcpy(&pcd_cmd.buff[2],offset,3);
	memcpy(&pcd_cmd.buff[5],length,3);
	len = (len|length[2])<<16;
	len = (len|length[1])<<8;
	len = (len|length[0]);
	pcd_cmd.length = 8+len;
	if(pcd_cmd.length<=60)
	{
		memcpy(&pcd_cmd.buff[8],data_buf,len);
		status = des_cmd_transceive(pi);
		if(status == MI_OK)
		{
			if(pcd_cmd.buff[0]==0x00)
			{
				return status;
			}
			else
			{
				return pcd_cmd.buff[0];
			}
		}
	}
	else
	{
		pcd_cmd.length = 60;
		memcpy(&pcd_cmd.buff[8],data_buf,52);
		status = des_cmd_transceive(pi);
		if(status == MI_OK)
		{
			len -= 52;
			if(pcd_cmd.buff[0]==0xaf)
			{
				while(1)
				{
						if(len<=59)
						{
							pcd_cmd.length = 1+len;
							pcd_cmd.buff[0] = 0xaf;
							memcpy(&pcd_cmd.buff[1],&data_buf[52+59*i],len);
							status = des_cmd_transceive(pi);
							if(status == 0x00)
							{
								if(pcd_cmd.buff[0]==0x00)
								{
										return status;
								}
								else
								{
									return pcd_cmd.buff[0];
								}
							}	
						}
						else
						{
							len-=59;
							pcd_cmd.length = 60;
							pcd_cmd.buff[0] = 0xaf;
							memcpy(&pcd_cmd.buff[1],&data_buf[52+59*i],59);
							status = des_cmd_transceive(pi);
							if(status == 0x00)
							{
								if(pcd_cmd.buff[0]!=0xaf)
								{
									return pcd_cmd.buff[0];
								}
							}
						}
					}
				}
				else
				{
					return pcd_cmd.buff[0];
				}
		}
		else
		{
			return status;
		}
	}
	return status;
}

//PPS
void DES_PPS()
{
	unsigned char crc_lsb = 0,i;
  unsigned char crc_msb = 0;
  int8_t status = MI_EMPTY;
  transceive_buffer  mf_com_data;
  transceive_buffer  *pi;
  pi = &mf_com_data;
	spi_write_reg(fifolevel_reg, 0x80);                    //clear fifo data
  spi_write_reg(recstate_reg, 0x7F);
	mf_com_data.mf_command =PCD_TRANSCEIVE;
	mf_com_data.mf_length  = 5;
	mf_com_data.mf_data[0] = 0xD5;
	mf_com_data.mf_data[1] = 0x11;
	mf_com_data.mf_data[2] = 0x00;
	pcd_get_crc(CRC_A, 3, mf_com_data.mf_data, &crc_lsb, &crc_msb);
	mf_com_data.mf_data[3] = crc_lsb;
	mf_com_data.mf_data[4] = crc_msb;
	spi_write_reg(snd_byte_num_reg, mf_com_data.mf_length);
	spi_write_reg(snd_bit_num_reg, 0x00);
	status = pcd_com_transceive(pi);
	#if DEBUG
    if(status == MI_OK)
	{
		for(i=0;i<3;i++)
		{
			uart_printf(" %02x ",mf_com_data.mf_data[i]);
		}
		uart_printf("PPS OK\r\n");
	}
	else
	{
		uart_printf("PPS error %02x\r\n",status);
	}
    #endif
	
}

//获取模块信息	
int8_t des_moudle_in(moudle_in *buf)
{
//	uint8_t i;
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 1;
	pcd_cmd.buff[0] = 0x60;
	status = des_cmd_transceive(pi);
	if(status == MI_OK)
	{
		if(pcd_cmd.buff[0]==0xAF)
		{
			memcpy(buf->moudle_hard,&pcd_cmd.buff[1],7);
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	
	pcd_cmd.length = 1;
	pcd_cmd.buff[0] = 0xaf;
	status = des_cmd_transceive(pi);
	if(status == MI_OK)
	{
		if(pcd_cmd.buff[0]==0xAF)
		{
			memcpy(buf->moudle_soft,&pcd_cmd.buff[1],7);
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	
	pcd_cmd.length = 1;
	status = des_cmd_transceive(pi);
	if(status == MI_OK)
	{
		if(pcd_cmd.buff[0]==0x00)
		{
			memcpy(buf->moudle,&pcd_cmd.buff[1],14);
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	return status;
}



//获取所有活动的应用
int8_t GetApplicationIDs(uint8_t *buf,uint8_t *len)
{
	uint8_t temp;
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 1;
	pcd_cmd.buff[0] = 0x6a;
	status = des_cmd_transceive(pi);
	if(status == MI_OK)
	{
		if(pcd_cmd.buff[0]==0x00)
		{
			len[0] = (pcd_cmd.length -1);
			memcpy(buf,&pcd_cmd.buff[1],len[0]);
		}
		else if(pcd_cmd.buff[0]==0xaf)
		{
			len[0] = pcd_cmd.length -1;
			memcpy(buf,pcd_cmd.buff,len[0]);

			pcd_cmd.length = 1;
			pcd_cmd.buff[0] = 0xaf;
			status = des_cmd_transceive(pi);
			if(0x00 == status)
			{
				temp = (pcd_cmd.length -1);
				memcpy(&buf[len[0]],&pcd_cmd.buff[1],temp);
				len[0] = len[0]+temp;
			}
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	return status;
}


//初始化PICC
int8_t FormatPICC()
{
	int8_t status = MI_EMPTY;
	uint8_t i;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 1;
	pcd_cmd.buff[0] = DESFIRE_PICCFO;
	status = des_cmd_transceive(pi);
	if(status == MI_OK)
	{
		i=0;
		while(i<100)
		{
			status = DES_SBLOCK();
			if(status == 0x00)
			{
				break;
			}
			i++;
		}
	}
	return status;
}



/**
 * @brief des_cmd_transceive(pcd_cmd_t *pcd_cmd)
 * @param  pcd_cmd_t: 存放指令
 * @param  :
 * @retval 
 */
int8_t des_cmd_transceive(pcd_cmd_t *pcd_cmd)
{
	unsigned char crc_lsb = 0;
  unsigned char crc_msb = 0;
  int8_t status = MI_EMPTY;
	uint8_t xdata i=0;
  transceive_buffer  mf_com_data;
  transceive_buffer  *pi;
	uint8_t len_temp = pcd_cmd->length;//保存指令的长度
	pi = &mf_com_data;
	do
	{
		if(len_temp>60)
		{
			mf_com_data.mf_length = 60+4;//指令60个字节+pcb cid crc
			len_temp -= 60;
			pcb |= 0x10;//链接
		}
		else
		{
			mf_com_data.mf_length = len_temp+4;
			pcb &= ~0x10;//不链接
			i|=0x80;
		}
		mf_com_data.mf_command = PCD_TRANSCEIVE;	//rd522收发命令
		spi_write_reg(snd_byte_num_reg, mf_com_data.mf_length);
		spi_write_reg(snd_bit_num_reg, 0x00);
		mf_com_data.mf_data[0] = pcb;
		mf_com_data.mf_data[1] = PICC_CID;//cid
		memcpy(&mf_com_data.mf_data[2], &pcd_cmd->buff[(i&0x7f)*60], mf_com_data.mf_length-4);//拷贝命令数据
		spi_write_reg(fifolevel_reg,0x80);
		status = pcd_get_crc(CRC_A, mf_com_data.mf_length-2, mf_com_data.mf_data, &crc_lsb, &crc_msb);
		if(status != MI_OK) return status;
		mf_com_data.mf_data[mf_com_data.mf_length-2] = crc_lsb;
		mf_com_data.mf_data[mf_com_data.mf_length-1] = crc_msb;
		status = pcd_com_transceive(pi);//rd522发送命令
		if(status == MI_OK)
		{
			pcb ^= 0x01;//切换块号，pcb最低位为块号，初始时pcb应该为0x0a（不链接）
			pcd_cmd->length = mf_com_data.mf_length-4;							//返回的fmcos指令长度，需要减去pcb+cid+crc
			memcpy(pcd_cmd->buff, &mf_com_data.mf_data[2], pcd_cmd->length);	//拷贝fmcos返回的指令数据，最后两个字节为sw1和sw2
			i++;
		}
		else break;
	}while((i&0x80) == 0);
	return status;
}

/**
 * @brief desfire_keyVer(uint8_t *key,uint8_t *pkey)
 * @param  key: 16字节密钥
 * @param  pkey:存放段密钥
 * @param  key_no:存放段密钥
 * @retval MI_OK or xx
 */
int8_t desfire_keyVer(uint8_t *key,uint8_t *pkey,uint8_t key_no)
{
	uint8_t idata rndb[8],rnda[8],i,rndb1[8],rnda1[8];
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	for(i=0;i<8;i++)
	{
		if(key[i] != key[8+i])
		{
			return 0x02;
		}
	}
	pcd_cmd.length = 2;
	pcd_cmd.buff[0] = 0X0A;//DESFIRE_VER_KEY;
	pcd_cmd.buff[1] = key_no;
	status = des_cmd_transceive(pi);//发送第一次验证请求
	if(status == MI_OK)
	{
		if(pcd_cmd.buff[0]==0xaf)
		{
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	Tdes(1,&pcd_cmd.buff[1],key,rndb);
	for(i=0;i<7;i++)
	{
		rndb1[i] = rndb[i+1];
	}
	rndb1[7]=rndb[0];
	memset(rnda,0,8);
	Tdes(1,rnda,key,&pcd_cmd.buff[1]);
	for(i=0;i<8;i++)
	{
		rndb1[i] ^= pcd_cmd.buff[1+i];
	}
	Tdes(1,&rndb1,key,&pcd_cmd.buff[9]);
	pcd_cmd.buff[0] = 0xAF;
	pcd_cmd.length = 17;
	status = des_cmd_transceive(pi);//发送第二次验证请求
	if(status == MI_OK)
	{
		if(pcd_cmd.buff[0]==0x00)
		{
			Tdes(1,&pcd_cmd.buff[1],key,rnda1);
			for(i=0;i<7;i++)
			{
				rnda1[i] = rnda[i+1];
				if(rnda1[i] != rnda[i+1])
				{
					return 0xae;
				}
			}
			if(rnda1[7] != rnda[0])
			{
				return 0xae;
			}
			//rndafir1+rndbfir1+rndasec2+rndbfir2
//			memcpy(pkey,rnda,4);
//			memcpy(&pkey[4],rndb,4);
//			memcpy(&pkey[8],&rnda[4],4);
//			memcpy(&pkey[12],&rndb[4],4);
			//rndafir1+rndbfir1+rndafir1+rndbfir1
			memcpy(pkey,rnda,4);
			memcpy(&pkey[4],rndb,4);
			memcpy(&pkey[8],rnda,4);
			memcpy(&pkey[12],rndb,4);
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	return status;
}

/**
 * @brief des_select_app
 * @retval 
 */

int8_t des_select_app(uint8_t *aid)
{
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 4;
	pcd_cmd.buff[0] = DESFIRE_SEL_APP;
	memcpy(&pcd_cmd.buff[1],aid,3);
	status = des_cmd_transceive(pi);
	if(status == MI_OK)
	{
		if(pcd_cmd.buff[0]==0x00)
		{
			return status;
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	return status;
}

/**
 * @brief des_create_app
 * @param  aid: 3字节aid
 * @param  lev: 1字节应用设定
 * @param  key_num: 1字节用于加密的应用密钥数量设置
 * @retval 
 */
int8_t des_create_app(uint8_t *aid,uint8_t lev,uint8_t key_num)
{
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 6;
	pcd_cmd.buff[0] = DESFIRE_CREATE_APP;
	memcpy(&pcd_cmd.buff[1],aid,3);
	pcd_cmd.buff[4] = lev;
	pcd_cmd.buff[5] = key_num;
	status = des_cmd_transceive(pi);
	if(status == MI_OK)
	{
		if(pcd_cmd.buff[0]==0x00)
		{
			return status;
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	return status;
}

/**
 * @brief GetKeyVersion获取密钥信息
 * @param  aid: 3字节aid
 * @retval 
 */
int8_t GetKeyVersion(uint8_t key_no)
{
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 2;
	pcd_cmd.buff[0] = 0X64;
	pcd_cmd.buff[1] = key_no;
	status = des_cmd_transceive(pi);
	#if DEBUG
    if(status == MI_OK)
	{
		if(pcd_cmd.buff[0]==0x00)
		{
			uart_printf("0x00\r\n");
		}
		else
		{
			uart_printf("%02x\r\n",pcd_cmd.buff[0]);
		}
	}
	uart_printf(" %02x \r\n",pcd_cmd.buff[1]);
    #endif
	
	return status;
}


/**
 * @brief CreateValueFile 创建值文件
 * @param  file_no: 1字节文件标识符
 * @param  lower: 4字节值下限
 * @param  upper: 4字节值上限
 * @param  value: 4字节值初始值
 * @retval 
 */
int8_t CreateValueFile(uint8_t file_no,uint8_t *lower,uint8_t *upper,uint8_t *value)
{
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 18;
	pcd_cmd.buff[0] = DESFIRE_VALUE_FILE;  
	pcd_cmd.buff[1] = file_no;
	pcd_cmd.buff[2] = 0x00;
	pcd_cmd.buff[3] = 0x00;
	pcd_cmd.buff[4] = 0x00;
	memcpy(&pcd_cmd.buff[5],lower,4);
	memcpy(&pcd_cmd.buff[9],upper,4);
	memcpy(&pcd_cmd.buff[13],value,4);
	pcd_cmd.buff[17] = 0x00;
	status = des_cmd_transceive(pi);
		if(status == MI_OK)
	{
		if(pcd_cmd.buff[0]==0x00)
		{
			return status;
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	return status;
}

/**
 * @brief  DeleteFile 删除文件
 * @param  file_no: 1字节文件标识符
 * @retval 
 */
int8_t DeleteFile(uint8_t file_no)
{
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 2;
	pcd_cmd.buff[0] = DESFIRE_DELETE_FILE;  
	pcd_cmd.buff[1] = file_no;
	status = des_cmd_transceive(pi);
		if(status == MI_OK)
	{
		if(pcd_cmd.buff[0]==0x00)
		{
			return status;
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	return status;
}

/**
 * @brief  GetValue 读值文件
 * @param  file_no: 1字节文件标识符 明文
 * @param  da: 返回值
 * @retval 
 */
int8_t GetValue(uint8_t file_no,int *da)
{
	unsigned char bcc=0,statu;
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 2;
	pcd_cmd.buff[0] = DESFIRE_GETVALUE;  
	pcd_cmd.buff[1] = file_no;
	status = des_cmd_transceive(pi);
	if(status == MI_OK)
	{
		if(pcd_cmd.buff[0]==0x00)
		{
			
			#if DEBUG
            da[0] = pcd_cmd.buff[1];
			da[0] |= (pcd_cmd.buff[2]<<8);
			da[0] |= (pcd_cmd.buff[3]<<16);
			da[0] |= (pcd_cmd.buff[4]<<24);
			uart_printf(" %d \r\n",(int)da[0]);
			#else
			Uart2_PutChar(0xaa);
			Uart2_PutChar(ADDR);
			Uart2_PutChar(0x04);
			Uart2_PutChar(0x00);
			Uart2_PutChar(0x04);
			bcc ^=  0xaa;
			bcc ^=  ADDR;
			bcc ^=  0x04;
			bcc ^=  0x00;
			bcc ^=  0x04;
			for(statu =0;statu < 4;statu++)
			{
				bcc ^= pcd_cmd.buff[statu+1];
				Uart2_PutChar(pcd_cmd.buff[statu+1]);
			}
			bcc ^= 0xbb;
			Uart2_PutChar(0xbb);
			Uart2_PutChar(bcc);
            #endif
			return status;
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	return status;
}

/**
 * @brief  Credit 写值文件 
 * @param  file_no: 1字节文件标识符
 * @param  flag: 1加 ，0减
 * @param  data_buf: 4字节加减的数据 
 * @retval 
 */
int8_t Credit_Debit(uint8_t file_no,uint8_t flag,uint8_t *data_buf)
{
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 6;
	if(flag == 0)
	{
		pcd_cmd.buff[0] = DESFIRE_DEBIT;
	}
	else
	{
		pcd_cmd.buff[0] = DESFIRE_CREDI;  
	}
	pcd_cmd.buff[1] = file_no;
	memcpy(&pcd_cmd.buff[2],data_buf,4);
	status = des_cmd_transceive(pi);
	if(status == MI_OK)
	{
		if(pcd_cmd.buff[0]==0x00)
		{
			return status;
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	return status;
}

/**
 * @brief  CommitTransaction 使备份机制的文件生效
 * @retval 
 */

int8_t CommitTransaction(void)
{
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 1;
		pcd_cmd.buff[0] = 0xc7;  
	
	status = des_cmd_transceive(pi);
	if(status == MI_OK)
	{
		if(pcd_cmd.buff[0]==0x00)
		{
			return status;
		}
		else
		{
			//uart_printf("data error \r\n");
			return pcd_cmd.buff[0];
		}
	}
	return status;
}




/**
 * @brief  ClearRecordFile 清空记录文件
 * @param  file_no: 1字节文件标识符 
 * @retval 
 */
int8_t ClearRecordFile(uint8_t file_no)
{
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 2;
	pcd_cmd.buff[0] = 0XEB;  
	pcd_cmd.buff[1] = file_no;

	status = des_cmd_transceive(pi);
	if(status == MI_OK)
	{
		if(pcd_cmd.buff[0]==0x00)
		{
			return status;
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	return status;
}

/**
 * @brief  ChangeKey 更改密钥	只适用与更改主密钥或者changekey设置为0xe的时候使用
 * @param  new_key新密钥: 16字节新密钥
 * @param  d_key会话密钥: 16字节会话密钥
 * @retval 
 */
int8_t ChangeKey(uint8_t *new_key,uint8_t *d_key)
{
	uint8_t xdata i;
	unsigned char crc_lsb = 0;
  unsigned char crc_msb = 0;
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 26;
	pcd_cmd.buff[0] = 0xc4;  
	pcd_cmd.buff[1] = 0x00;
	spi_write_reg(fifolevel_reg,0x80);
	pcd_get_crc(CRC_A,16,new_key,&crc_lsb,&crc_msb);
	memcpy(&pcd_cmd.buff[2],new_key,16);
	pcd_cmd.buff[18] = crc_lsb;
	pcd_cmd.buff[19] = crc_msb;
	memset(&pcd_cmd.buff[20],0,6);
	Tdes(1,new_key,d_key,&pcd_cmd.buff[2]);
	for(i=0;i<8;i++)
	{
		new_key[8+i] ^= pcd_cmd.buff[2+i];
	}
	Tdes(1,&new_key[8],d_key,&pcd_cmd.buff[10]);
	for(i=0;i<8;i++)
	{
		 pcd_cmd.buff[18+i]^= pcd_cmd.buff[10+i];
	}
	Tdes(1,&pcd_cmd.buff[18],d_key,&pcd_cmd.buff[18]);
	status = des_cmd_transceive(pi);
	if(0x00 == status)
	{
		if(0x00 == pcd_cmd.buff[0])
		{
			return status;
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	else
	{
		if(status == -38)
		{
			//uart_printf("-38\r\n");
		}
	}
	return status;
}

void GetKeySettings()
{
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 1;
	pcd_cmd.buff[0] = 0X45;
	status = des_cmd_transceive(pi);
	if(0x00 == status)
	{
		if(0x00 == pcd_cmd.buff[0])
		{
			uart_printf("%02x %02x\r\n",pcd_cmd.buff[1],pcd_cmd.buff[2]);
		}
		else
		{
			uart_printf("%02x\r\n",pcd_cmd.buff[0]);
		}
	}
}

/**
 * @brief  ChangeKeySettings 更改密钥设定
 * @param  key_set旧密钥: 1字节参数
 * @param  d_key旧密钥: 16字节duan密钥参数
 * @retval 
 */
int8_t ChangeKeySettings(uint8_t key_set,uint8_t *d_key)
{
	unsigned char crc_lsb = 0;
  unsigned char crc_msb = 0;
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 9;
	pcd_cmd.buff[0] = 0x54;
	pcd_cmd.buff[1] = key_set;
	spi_write_reg(fifolevel_reg,0x80);
	pcd_get_crc(CRC_A,1,&pcd_cmd.buff[1],&crc_lsb,&crc_msb);
	pcd_cmd.buff[2] = crc_lsb;
	pcd_cmd.buff[3] = crc_msb;
	memset(&pcd_cmd.buff[4],0,5);
	Tdes(1,&pcd_cmd.buff[1],d_key,&pcd_cmd.buff[1]);
	status = des_cmd_transceive(pi);
	if(0x00 == status)
	{
		if(0x00 == pcd_cmd.buff[0])
		{
			return status;
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	else
	{
		if(status == -38)
		{
			//uart_printf("%d\r\n",status);
		}
	}
	return status;
}

/**
 * @brief  GetFileSettings 获取文件信息
 * @param  file_no: 1字节文件标识符参数
 * @param  file_file: 1字节文件类型返回值
 * @retval 
 */
int8_t GetFileSettings(uint8_t file_no,uint8_t *file_type)
{
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = 2;
	pcd_cmd.buff[0] = 0XF5;
	pcd_cmd.buff[1] = file_no;
	status = des_cmd_transceive(pi);
	if(0x00 == status)
	{
		if(0x00 == pcd_cmd.buff[0])
		{
			file_type[0] = pcd_cmd.buff[1];
			return status;
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	return status;
}

/**
 * @brief  DES_transmission i块数据透传
 * @param  length: 数据长度
 * @param  buf: 透传数据
 */
int8_t DES_transmission(uint8_t *length,uint8_t *buf)
{
	int8_t status = MI_EMPTY;
	pcd_cmd_t pcd_cmd;
	pcd_cmd_t *pi;
	pi = &pcd_cmd;
	pcd_cmd.length = length[0];
	memcpy(pcd_cmd.buff,buf,length[0]);
	status = des_cmd_transceive(pi);
	if(0x00 == status)
	{

		if(0x00 == pcd_cmd.buff[0]||0xaf == pcd_cmd.buff[0])
		{
			length[0] = pcd_cmd.length+1;
			memcpy(buf,pcd_cmd.buff,length[0]);
			pcd_cmd.buff[pcd_cmd.length] = pcb;
		}
		else
		{
			return pcd_cmd.buff[0];
		}
	}
	return status;
}


/**
 * @brief  transmission 数据透传
 * @param  length: 数据长度
 * @param  buf: 透传数据
 */
int8_t desocd_transmission(uint8_t *length,uint8_t *buf)
{
	int8_t status = MI_EMPTY;
  transceive_buffer  mf_com_data;
  transceive_buffer  *pi;
  pi = &mf_com_data;
	spi_write_reg(fifolevel_reg, 0x80);                    //clear fifo data
  spi_write_reg(recstate_reg, 0x7F);
	mf_com_data.mf_command =PCD_TRANSCEIVE;
	mf_com_data.mf_length  = length[0];
	memcpy(mf_com_data.mf_data,buf,length[0]);
	spi_write_reg(snd_byte_num_reg, mf_com_data.mf_length);
	spi_write_reg(snd_bit_num_reg, 0x00);
	status = pcd_com_transceive(pi);
	if(0x00 == status)
	{
		length[0] = mf_com_data.mf_length+1;
		memcpy(buf,mf_com_data.mf_data,mf_com_data.mf_length);
		if(mf_com_data.mf_data[2] == 0x00&&mf_com_data.mf_data[1] == 0x01&&(mf_com_data.mf_data[0]==0x0a||mf_com_data.mf_data[0]==0x0b))
		{
			pcb ^= 0x01;
			
		}
		buf[mf_com_data.mf_length] = pcb;
	}
	return status;
}
//返回WTX
int8_t DES_SBLOCK()
{
	int8_t status = MI_EMPTY;
  transceive_buffer  mf_com_data;
  transceive_buffer  *pi;
  pi = &mf_com_data;
	spi_write_reg(fifolevel_reg, 0x80);                    //clear fifo data
  spi_write_reg(recstate_reg, 0x7F);
	mf_com_data.mf_command =PCD_TRANSCEIVE;
	mf_com_data.mf_length  = 5;
	mf_com_data.mf_data[0] = 0xfa;
	mf_com_data.mf_data[1] = PICC_CID;
	mf_com_data.mf_data[2] = 0x01;
	//crc
	mf_com_data.mf_data[3] = 0x0b;
	mf_com_data.mf_data[4] = 0x52;
	spi_write_reg(snd_byte_num_reg,mf_com_data.mf_length);
	spi_write_reg(snd_bit_num_reg,0x00);
	status = pcd_com_transceive(pi);
	if(status == 0x00)
	{
		if(mf_com_data.mf_data[2] == 0x00)
		{
			return status;
		}
		else
		{
			return 0x01;
		}
	}
	return status;
}

void uart_rec_buf(uint8_t status,uint8_t command,uint8_t *buf,uint8_t len)
{
	#if DEBUG
	
    unsigned char bcc=0;
	uart_printf("RX:%02bx %02bx %02bx %02bx %02bx ",0xaa,ADDR,command,status,len);
	bcc ^=  0xaa;
	bcc ^=  ADDR;
	bcc ^=  command;
	bcc ^=  status;
	bcc ^=  len;
	for(status =0;status < len;status++)
	{
		bcc ^= buf[status];
		uart_printf("%02bx ",buf[status]);
	}
	bcc ^= 0xbb;
	uart_printf("%02bx %02bx\r\n",0xbb,bcc);
	
	#else
	
	unsigned char bcc=0;
	Uart2_PutChar(0xaa);
	Uart2_PutChar(ADDR);
	Uart2_PutChar(command);
	Uart2_PutChar(status);
	Uart2_PutChar(len);
	bcc ^=  0xaa;
	bcc ^=  ADDR;
	bcc ^=  command;
	bcc ^=  status;
	bcc ^=  len;
	for(status =0;status < len;status++)
	{
		bcc ^= buf[status];
		Uart2_PutChar(buf[status]);
	}
	bcc ^= 0xbb;
	Uart2_PutChar(0xbb);
	Uart2_PutChar(bcc);
    #endif
}